package com.atlantis.apps.socius.tabs;

import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.RadioGroup.LayoutParams;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;
import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.Toast;

import com.atlantis.apps.facebook.BaseDialogListener;
import com.atlantis.apps.facebook.BaseRequestListener;
import com.atlantis.apps.facebook.LoginButton;
import com.atlantis.apps.facebook.SessionEvents;
import com.atlantis.apps.facebook.SessionEvents.AuthListener;
import com.atlantis.apps.facebook.SessionEvents.LogoutListener;
import com.atlantis.apps.facebook.UpdateStatusResultDialog;
import com.atlantis.apps.facebook.UploadPhotoResultDialog;
import com.atlantis.apps.facebook.Utility;
import com.atlantis.apps.socius.R;
import com.atlantis.apps.socius.R.drawable;
import com.atlantis.apps.socius.service.SNBackgroundService;
import com.atlantis.apps.socius.tabs.fragments.SNFeedFragment;
import com.atlantis.apps.socius.tabs.fragments.SNFriendsFragment;
import com.atlantis.apps.socius.tabs.fragments.SNGroupsFragment;
import com.atlantis.apps.socius.util.SNConstants;
import com.atlantis.apps.socius.util.SNPageAdapter;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;

/**
 * The <code>TabsViewPagerFragmentActivity</code> class implements the Fragment activity that maintains a TabHost using a ViewPager.
 * @author mwho
 */
public class SNTabsFragmentActivity extends FragmentActivity implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {

	private TabHost mTabHost;
	private ViewPager mViewPager;
	private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, SNTabsFragmentActivity.TabInfo>();
	private SNPageAdapter mPagerAdapter;
	private DataUpdateReceiver dataUpdateReceiver;
    private Handler mHandler;
    private TextView mText;
    private ImageView mUserPic;
    ProgressDialog dialog;

    private LoginButton mLoginButton;
    final static int AUTHORIZE_ACTIVITY_RESULT_CODE = 0;
    final static int PICK_EXISTING_PHOTO_RESULT_CODE = 1;
    String[] permissions = { "offline_access", "publish_stream", "user_photos", "publish_checkins",
    "photo_upload" };
    
    /**
	 *
	 * @author mwho
	 * Maintains extrinsic info of a tab's construct
	 */
    @SuppressWarnings("unused")
	private class TabInfo {
		 private String tag;
		private Class<?> clss;
		private Bundle args;
		private Fragment fragment;
         TabInfo(String tag, Class<?> clazz, Bundle args) {
        	 this.tag = tag;
        	 this.clss = clazz;
        	 this.args = args;
         }

	}
	/**
	 * A simple factory that returns dummy views to the Tabhost
	 * @author mwho
	 */
	class TabFactory implements TabContentFactory {

		private final Context mContext;

	    /**
	     * @param context
	     */
	    public TabFactory(Context context) {
	        mContext = context;
	    }

	    /** (non-Javadoc)
	     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
	     */
	    public View createTabContent(String tag) {
	        View v = new View(mContext);
	        v.setMinimumWidth(0);
	        v.setMinimumHeight(0);
	        return v;
	    }

	}
	/** (non-Javadoc)
	 * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
	 */
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// Inflate the layout
		setContentView(R.layout.tabs);

		// Initialise the TabHost
		this.initialiseTabHost(savedInstanceState);
		if (savedInstanceState != null) {
            mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
        }

        mHandler = new Handler();
        mText = (TextView) findViewById(R.id.txt);
        mUserPic = (ImageView) findViewById(R.id.user_pic);

        _login();
        
        // Intialise ViewPager
		this.intialiseViewPager();
		
		Log.d(getClass().getSimpleName(), "Activity Created");
	}

    private void _login() {
		try {
			Log.d(getClass().getSimpleName(), "Login");

	        // Create the Facebook Object using the app id.
	        Utility.mFacebook = new Facebook(SNConstants.FACEBOOKAPPID);
	        // Instantiate the asynrunner object for asynchronous api calls.
	        Utility.mAsyncRunner = new AsyncFacebookRunner(Utility.mFacebook);

	        SessionEvents.addAuthListener(new FbAPIsAuthListener());
	        SessionEvents.addLogoutListener(new FbAPIsLogoutListener());

	        mLoginButton = (LoginButton) findViewById(R.id.login);
	        mLoginButton.init(this, AUTHORIZE_ACTIVITY_RESULT_CODE, Utility.mFacebook, permissions);
	        Utility.mFacebook.authorize(this, permissions, AUTHORIZE_ACTIVITY_RESULT_CODE, new LoginDialogListener());

	    } catch (Exception e) {
			Log.d(getBaseContext().getClass().getSimpleName(), "Check your Settings!");
			e.printStackTrace();
		}
	}
    private final class LoginDialogListener implements DialogListener {
        
        public void onComplete(Bundle values) {
            SessionEvents.onLoginSuccess();
        }

        
        public void onFacebookError(FacebookError error) {
            SessionEvents.onLoginError(error.getMessage());
        }

        
        public void onError(DialogError error) {
            SessionEvents.onLoginError(error.getMessage());
        }

        
        public void onCancel() {
            SessionEvents.onLoginError("Action Canceled");
        }
    }
    /*
     * The Callback for notifying the application when authorization succeeds or
     * fails.
     */

    public class FbAPIsAuthListener implements AuthListener {

        public void onAuthSucceed() {
            requestUserData();
        }

        public void onAuthFail(String error) {
            mText.setText("Login Failed: " + error);
        }
    }

    /*
     * The Callback for notifying the application when log out starts and
     * finishes.
     */
    public class FbAPIsLogoutListener implements LogoutListener {
        public void onLogoutBegin() {
            mText.setText("Logging out...");
        }

        public void onLogoutFinish() {
            mText.setText("You have logged out! ");
            mUserPic.setImageBitmap(null);
        }
    }
    
    /** (non-Javadoc)
     * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
     */
    protected void onSaveInstanceState(Bundle outState) {
        outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
        super.onSaveInstanceState(outState);
    }

    /**
     * Initialise ViewPager
     */
    private void intialiseViewPager() {

		List<Fragment> fragments = new Vector<Fragment>();
		fragments.add(Fragment.instantiate(this, SNFeedFragment.class.getName()));
		fragments.add(Fragment.instantiate(this, SNFriendsFragment.class.getName()));
		fragments.add(Fragment.instantiate(this, SNGroupsFragment.class.getName()));
		this.mPagerAdapter  = new SNPageAdapter(super.getSupportFragmentManager(), fragments);
		this.mViewPager = (ViewPager)super.findViewById(R.id.viewpager);
		this.mViewPager.setAdapter(this.mPagerAdapter);
		this.mViewPager.setOnPageChangeListener(this);
    }

	/**
	 * Initialise the Tab Host
	 */
	private void initialiseTabHost(Bundle args) {
		mTabHost = (TabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup();

        TabInfo tabInfo = null;
        SNTabsFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("Feed"), ( tabInfo = new TabInfo("Tab1", SNFeedFragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        SNTabsFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("Friends"), ( tabInfo = new TabInfo("Tab2", SNFriendsFragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        SNTabsFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Groups"), ( tabInfo = new TabInfo("Tab3", SNGroupsFragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);

        mTabHost.setOnTabChangedListener(this);

        //Tab styling stuff. Check if this can be moved to xml
        TabWidget tabWidget = (TabWidget) findViewById(android.R.id.tabs);
        tabWidget.setStripEnabled(false);
        
        tabWidget.setHorizontalFadingEdgeEnabled(true);

        for (int i=0; i< tabWidget.getChildCount(); i++)
        {
            tabWidget.getChildAt(i).setLayoutParams(new LayoutParams(180,40));

        	tabWidget.getChildAt(i).setBackgroundResource(drawable.tab);
        	TextView tv = (TextView) tabWidget.getChildAt(i).findViewById(android.R.id.title);
        	tv.setTextColor(this.getResources().getColorStateList(R.drawable.tab_selector));        
        	
        }
	}

	/**
	 * Add Tab content to the Tabhost
	 * @param activity
	 * @param tabHost
	 * @param tabSpec
	 * @param clss
	 * @param args
	 */
	private static void AddTab(SNTabsFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
		// Attach a Tab view factory to the spec
		tabSpec.setContent(activity.new TabFactory(activity));
        tabHost.addTab(tabSpec);
	}

	/** (non-Javadoc)
	 * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
	 */
	public void onTabChanged(String tag) {
		//TabInfo newTab = this.mapTabInfo.get(tag);
		int pos = this.mTabHost.getCurrentTab();
		this.mViewPager.setCurrentItem(pos);
    }

	/* (non-Javadoc)
	 * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
	 */
	public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

	/* (non-Javadoc)
	 * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
	 */
	public void onPageSelected(int position) {
		this.mTabHost.setCurrentTab(position);
	}

	/* (non-Javadoc)
	 * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
	 */
	public void onPageScrollStateChanged(int state) {}

	public boolean onCreateOptionsMenu(Menu menu) {
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.menu, menu);
	    return true;
	}

	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.settings:
			Log.d(getClass().getSimpleName(), "Settings Clicked");
	        return true;
	    case R.id.help:
			Log.d(getClass().getSimpleName(), "Help Clicked");
	        return true;
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}

    public void onResume() {
        super.onResume();
		// Start Background Service
		this.getApplicationContext().startService(new Intent(this, SNBackgroundService.class));

		if (dataUpdateReceiver == null) dataUpdateReceiver = new DataUpdateReceiver();
		IntentFilter intentFilter = new IntentFilter(SNConstants.REFRESH_DATA_INTENT);
		registerReceiver(dataUpdateReceiver, intentFilter);
		
		Log.d(getClass().getSimpleName(), "Activity Resumed");
    }
    
    public void onPause(){
        super.onPause();
    	if (dataUpdateReceiver != null) unregisterReceiver(dataUpdateReceiver);
    }
    
    public void onStop() {
        super.onStop();
		// Stop Background Service
		this.getApplicationContext().stopService(new Intent(this, SNBackgroundService.class));
		Log.d(getClass().getSimpleName(), "Activity Stopped");
    }

    private class DataUpdateReceiver extends BroadcastReceiver {
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(SNConstants.REFRESH_DATA_INTENT)) {
            //Do stuff - maybe update my view based on the changed DB contents
            }
        }
    }
    /*
     * Request user name, and picture to show on the main screen.
     */
    public void requestUserData() {
        //mText.setText("Fetching user name, profile pic...");
        Bundle params = new Bundle();
        params.putString("fields", "name, picture");
        Utility.mAsyncRunner.request("me", params, new UserRequestListener());
    }

    /*
     * callback for the feed dialog which updates the profile status
     */
    public class UpdateStatusListener extends BaseDialogListener {
        public void onComplete(Bundle values) {
            final String postId = values.getString("post_id");
            if (postId != null) {
                new UpdateStatusResultDialog(SNTabsFragmentActivity.this, "Update Status executed", values)
                        .show();
            } else {
                Toast toast = Toast.makeText(getApplicationContext(), "No wall post made",
                        Toast.LENGTH_SHORT);
                toast.show();
            }
        }

        @Override
        public void onFacebookError(FacebookError error) {
            Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
                    Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel() {
            Toast toast = Toast.makeText(getApplicationContext(), "Update status cancelled",
                    Toast.LENGTH_SHORT);
            toast.show();
        }
    }

    /*
     * callback for the apprequests dialog which sends an app request to user's
     * friends.
     */
    public class AppRequestsListener extends BaseDialogListener {
        public void onComplete(Bundle values) {
            Toast toast = Toast.makeText(getApplicationContext(), "App request sent",
                    Toast.LENGTH_SHORT);
            toast.show();
        }

        public void onFacebookError(FacebookError error) {
            Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
                    Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel() {
            Toast toast = Toast.makeText(getApplicationContext(), "App request cancelled",
                    Toast.LENGTH_SHORT);
            toast.show();
        }
    }


    /*
     * callback for the photo upload
     */
    public class PhotoUploadListener extends BaseRequestListener {

        public void onComplete(final String response, final Object state) {
            dialog.dismiss();
            mHandler.post(new Runnable() {
                public void run() {
                    new UploadPhotoResultDialog(SNTabsFragmentActivity.this, "Upload Photo executed", response)
                            .show();
                }
            });
        }

        public void onFacebookError(FacebookError error) {
            dialog.dismiss();
            Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
                    Toast.LENGTH_LONG).show();
        }
    }

    public class FQLRequestListener extends BaseRequestListener {

        public void onComplete(final String response, final Object state) {
            mHandler.post(new Runnable() {
                public void run() {
                    Toast.makeText(getApplicationContext(), "Response: " + response,
                            Toast.LENGTH_LONG).show();
                }
            });
        }

        public void onFacebookError(FacebookError error) {
            Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
                    Toast.LENGTH_LONG).show();
        }
    }
    /*
     * Callback for fetching current user's name, picture, uid.
     */
    public class UserRequestListener extends BaseRequestListener {

        public void onComplete(final String response, final Object state) {
            JSONObject jsonObject;
            try {
                jsonObject = new JSONObject(response);

                final String picURL = jsonObject.getString("picture");
                final String name = jsonObject.getString("name");
                Utility.userUID = jsonObject.getString("id");

               mHandler.post(new Runnable() {
                    public void run() {
                        mText.setText("Welcome " + name + "!");
                        mUserPic.setImageBitmap(Utility.getBitmap(picURL));
                    }
                });

            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

